﻿// Inner Fire 游戏引擎库
// Scene - 场景类
//
// Copyright (c) 2025 by 尔西大帝. All rights reserved.
//
// 所属层级：框架层(5)
// 用于控制一个场景内的东西。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2025-01-13

#pragma once

#include <dx/mesh/tree_sprite.h>
#include <game/animation/animation.h>
#include <game/map/map.h>
#include <game/object/object_factory.h>
#include <ui/component/label.h>
#include <game/resource/material.h>
#include <game/physics/physics_world.h>
#include <game/physics/collider_world.h>
#include <game/map/scene_info.h>

using namespace ikit;

namespace ifire::ui{
class UIManager;

}

namespace ifire::game {
class GameManager;

class Scene {
public:
  Scene(GameManager* gm, const SceneInfo& info);
  Scene(const Scene& lhs) = delete;
  Scene& operator=(const Scene& lhs) = delete;
  ~Scene() = default;

  const ikit::sstr Name() const { return info_.name; }

  // 得到当前Scene（Singleton模式）
  static Scene* GetCurrentScene() { return current_scene_; }
  // 设置当前Scene（Singleton模式）
  static void SetCurrentScene(Scene* scene) { current_scene_ = scene; }

  // 载入一个Scene
  void Load();
  // 创建调试层
  void BuildDebugLayer();
  // 更新项目
  void FixedUpdate();

  // 输出一个调试信息
  size_t PrintDebug(const char* format, ...);
  // 设置DEBUG信息
  void SetDebugMessage(int index, const char* text, size_t len);

  // 根据名称设置一个RenderItem的绘制参数。名称为"主Mesh名:子Mesh名"。
  // 如果省略子Mesh名。则获得默认（第一个）子Mesh。
  void SetRenderObject(ikit::sstr name, dx::RenderItem* item);

  // 创建一个物理世界
  PhysicsWorld* CreatePhysicsWorld(ikit::sstr name);
  // 获得一个物理世界
  PhysicsWorld* GetPhysicsWorld(ikit::sstr name);

  // 创建一个碰撞世界（角色）
  ColliderWorld* CreateCharaColliderWorld();
  // 得到角色的碰撞世界
  ColliderWorld* GetCharaColliderWorld();

  //
  // 属性访问
  //
  ui::UIManager* GetUIManager();
  GameManager* GM() { return gm_; }
  const std::string& GetUILayout() { return info_.ui_layout; }
  bool HasMap() const { return !info_.map_file.empty(); }
  bool HasSkyBox() const { return !info_.sky_box.empty(); }
  const eastl::vector<GameObjectPtr>& Objects() { return objects_; }
  inline ObjectFactory* GetObjectFactory() const {
    return object_factory_.get();
  }
  const std::string& GetLuaScript() const { return info_.lua_script; }

private:
  GameManager* gm_;
  const SceneInfo& info_;

  // 保存当前的Scene（Singleton模式）
  static Scene* current_scene_;
  
  // 用于生成对象
  std::unique_ptr<ObjectFactory> object_factory_;
  // 用于角色的碰撞体
  std::unique_ptr<ColliderWorld> chara_collider_;
  // 用于管理物理世界
  eastl::vector<std::unique_ptr<PhysicsWorld>> physics_worlds_;
  // 项目的对象
  eastl::vector<GameObjectPtr> objects_;
  // 用于水体的更新
  Material* water_;

  ui::Label* fps_text_ = nullptr;
  ui::Label* debug_text_ = nullptr;
};

using ScenePtr = std::unique_ptr<Scene>;

} // namespace ifire::game